#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""事件总线模块，用于组件间通信"""

import threading
from typing import Dict, List, Callable, Any, Optional, Set, Tuple, Union
import inspect


class EventBus:
    """简单的事件总线实现，用于应用程序组件间的通信
    
    支持事件的订阅、发布、取消订阅等功能，线程安全
    """
    
    def __init__(self):
        """初始化事件总线"""
        # 存储事件名称和对应的回调函数列表
        self._events: Dict[str, List[Callable]] = {}
        # 存储回调函数和对应的事件名称（用于快速取消订阅）
        self._callbacks_to_events: Dict[Callable, Set[str]] = {}
        # 线程锁，保证线程安全
        self._lock = threading.RLock()
        # 启用/禁用标志
        self._enabled = True
    
    def subscribe(self, event_name: str, callback: Callable) -> bool:
        """订阅事件
        
        Args:
            event_name: 事件名称
            callback: 回调函数
            
        Returns:
            bool: 是否订阅成功
        """
        if not callable(callback):
            return False
        
        with self._lock:
            # 如果事件不存在，创建新的事件列表
            if event_name not in self._events:
                self._events[event_name] = []
            
            # 如果回调函数已经订阅了该事件，不重复添加
            if callback in self._events[event_name]:
                return True
            
            # 添加回调函数到事件列表
            self._events[event_name].append(callback)
            
            # 更新回调函数到事件名称的映射
            if callback not in self._callbacks_to_events:
                self._callbacks_to_events[callback] = set()
            self._callbacks_to_events[callback].add(event_name)
            
            return True
    
    def unsubscribe(self, event_name: str, callback: Callable) -> bool:
        """取消订阅特定事件的回调函数
        
        Args:
            event_name: 事件名称
            callback: 回调函数
            
        Returns:
            bool: 是否取消订阅成功
        """
        with self._lock:
            # 检查事件是否存在
            if event_name not in self._events:
                return False
            
            # 检查回调函数是否订阅了该事件
            if callback not in self._events[event_name]:
                return False
            
            # 从事件列表中移除回调函数
            self._events[event_name].remove(callback)
            
            # 如果事件列表为空，删除该事件
            if not self._events[event_name]:
                del self._events[event_name]
            
            # 更新回调函数到事件名称的映射
            if callback in self._callbacks_to_events:
                self._callbacks_to_events[callback].remove(event_name)
                # 如果回调函数没有订阅任何事件，从映射中删除
                if not self._callbacks_to_events[callback]:
                    del self._callbacks_to_events[callback]
            
            return True
    
    def unsubscribe_all(self, callback: Callable) -> int:
        """取消回调函数订阅的所有事件
        
        Args:
            callback: 回调函数
            
        Returns:
            int: 取消订阅的事件数量
        """
        with self._lock:
            # 检查回调函数是否订阅了任何事件
            if callback not in self._callbacks_to_events:
                return 0
            
            # 获取回调函数订阅的所有事件
            event_names = list(self._callbacks_to_events[callback])
            
            # 取消订阅所有事件
            count = 0
            for event_name in event_names:
                if self.unsubscribe(event_name, callback):
                    count += 1
            
            return count
    
    def publish(self, event_name: str, *args, **kwargs) -> int:
        """发布事件
        
        Args:
            event_name: 事件名称
            *args: 传递给回调函数的位置参数
            **kwargs: 传递给回调函数的关键字参数
            
        Returns:
            int: 成功调用的回调函数数量
        """
        # 检查事件总线是否启用
        if not self._enabled:
            return 0
        
        # 复制回调函数列表，避免在调用过程中修改列表
        callbacks = []
        with self._lock:
            if event_name in self._events:
                callbacks = self._events[event_name].copy()
        
        # 调用所有回调函数
        count = 0
        for callback in callbacks:
            try:
                callback(*args, **kwargs)
                count += 1
            except Exception as e:
                # 捕获异常，避免影响其他回调函数
                print(f"Error calling callback for event '{event_name}': {e}")
        
        return count
    
    def has_subscribers(self, event_name: str) -> bool:
        """检查事件是否有订阅者
        
        Args:
            event_name: 事件名称
            
        Returns:
            bool: 是否有订阅者
        """
        with self._lock:
            return event_name in self._events and len(self._events[event_name]) > 0
    
    def get_subscribers_count(self, event_name: str) -> int:
        """获取事件的订阅者数量
        
        Args:
            event_name: 事件名称
            
        Returns:
            int: 订阅者数量
        """
        with self._lock:
            if event_name not in self._events:
                return 0
            return len(self._events[event_name])
    
    def get_event_names(self) -> List[str]:
        """获取所有注册的事件名称
        
        Returns:
            List[str]: 事件名称列表
        """
        with self._lock:
            return list(self._events.keys())
    
    def clear(self, event_name: Optional[str] = None) -> None:
        """清除事件订阅
        
        Args:
            event_name: 事件名称，如果为None则清除所有事件
        """
        with self._lock:
            if event_name is None:
                # 清除所有事件
                self._events.clear()
                self._callbacks_to_events.clear()
            elif event_name in self._events:
                # 清除特定事件
                # 先更新回调函数到事件名称的映射
                for callback in self._events[event_name]:
                    if callback in self._callbacks_to_events:
                        self._callbacks_to_events[callback].remove(event_name)
                        if not self._callbacks_to_events[callback]:
                            del self._callbacks_to_events[callback]
                # 然后删除事件
                del self._events[event_name]
    
    def enable(self) -> None:
        """启用事件总线"""
        with self._lock:
            self._enabled = True
    
    def disable(self) -> None:
        """禁用事件总线"""
        with self._lock:
            self._enabled = False
    
    def is_enabled(self) -> bool:
        """检查事件总线是否启用
        
        Returns:
            bool: 是否启用
        """
        with self._lock:
            return self._enabled
    
    def __enter__(self) -> 'EventBus':
        """支持上下文管理器协议"""
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb) -> None:
        """上下文管理器退出时清理资源"""
        self.clear()
    
    def __len__(self) -> int:
        """获取注册的事件数量
        
        Returns:
            int: 事件数量
        """
        with self._lock:
            return len(self._events)


class EventEmitter:
    """事件发射器基类，可以被继承以提供事件功能"""
    
    def __init__(self):
        """初始化事件发射器"""
        self._event_bus = EventBus()
    
    def on(self, event_name: str, callback: Callable) -> 'EventEmitter':
        """订阅事件（链式调用）
        
        Args:
            event_name: 事件名称
            callback: 回调函数
            
        Returns:
            EventEmitter: 自身，用于链式调用
        """
        self._event_bus.subscribe(event_name, callback)
        return self
    
    def off(self, event_name: str, callback: Callable) -> 'EventEmitter':
        """取消订阅事件（链式调用）
        
        Args:
            event_name: 事件名称
            callback: 回调函数
            
        Returns:
            EventEmitter: 自身，用于链式调用
        """
        self._event_bus.unsubscribe(event_name, callback)
        return self
    
    def off_all(self, callback: Callable) -> 'EventEmitter':
        """取消回调函数订阅的所有事件（链式调用）
        
        Args:
            callback: 回调函数
            
        Returns:
            EventEmitter: 自身，用于链式调用
        """
        self._event_bus.unsubscribe_all(callback)
        return self
    
    def emit(self, event_name: str, *args, **kwargs) -> int:
        """发布事件
        
        Args:
            event_name: 事件名称
            *args: 传递给回调函数的位置参数
            **kwargs: 传递给回调函数的关键字参数
            
        Returns:
            int: 成功调用的回调函数数量
        """
        return self._event_bus.publish(event_name, *args, **kwargs)
    
    def has_listeners(self, event_name: str) -> bool:
        """检查事件是否有监听器
        
        Args:
            event_name: 事件名称
            
        Returns:
            bool: 是否有监听器
        """
        return self._event_bus.has_subscribers(event_name)
    
    def listeners_count(self, event_name: str) -> int:
        """获取事件的监听器数量
        
        Args:
            event_name: 事件名称
            
        Returns:
            int: 监听器数量
        """
        return self._event_bus.get_subscribers_count(event_name)
    
    def event_names(self) -> List[str]:
        """获取所有注册的事件名称
        
        Returns:
            List[str]: 事件名称列表
        """
        return self._event_bus.get_event_names()
    
    def clear_events(self, event_name: Optional[str] = None) -> 'EventEmitter':
        """清除事件监听器
        
        Args:
            event_name: 事件名称，如果为None则清除所有事件
            
        Returns:
            EventEmitter: 自身，用于链式调用
        """
        self._event_bus.clear(event_name)
        return self


class EventFilter:
    """事件过滤器，可以在事件传递过程中进行过滤和转换"""
    
    def __init__(self, event_bus: EventBus):
        """初始化事件过滤器
        
        Args:
            event_bus: 事件总线实例
        """
        self._event_bus = event_bus
        self._filters: Dict[str, List[Callable]] = {}
        self._lock = threading.RLock()
    
    def add_filter(self, event_name: str, filter_func: Callable) -> bool:
        """添加事件过滤器
        
        Args:
            event_name: 事件名称
            filter_func: 过滤函数，接收事件数据，返回过滤后的数据
            
        Returns:
            bool: 是否添加成功
        """
        if not callable(filter_func):
            return False
        
        with self._lock:
            if event_name not in self._filters:
                self._filters[event_name] = []
            
            if filter_func in self._filters[event_name]:
                return True
            
            self._filters[event_name].append(filter_func)
            return True
    
    def remove_filter(self, event_name: str, filter_func: Callable) -> bool:
        """移除事件过滤器
        
        Args:
            event_name: 事件名称
            filter_func: 过滤函数
            
        Returns:
            bool: 是否移除成功
        """
        with self._lock:
            if event_name not in self._filters:
                return False
            
            if filter_func not in self._filters[event_name]:
                return False
            
            self._filters[event_name].remove(filter_func)
            
            if not self._filters[event_name]:
                del self._filters[event_name]
            
            return True
    
    def apply_filters(self, event_name: str, data: Any, *args, **kwargs) -> Any:
        """应用事件过滤器
        
        Args:
            event_name: 事件名称
            data: 要过滤的数据
            *args: 额外的参数
            **kwargs: 额外的关键字参数
            
        Returns:
            Any: 过滤后的数据
        """
        # 复制过滤器列表
        filters = []
        with self._lock:
            if event_name in self._filters:
                filters = self._filters[event_name].copy()
        
        # 应用所有过滤器
        result = data
        for filter_func in filters:
            try:
                # 检查过滤器函数的参数数量
                sig = inspect.signature(filter_func)
                param_count = len(sig.parameters)
                
                if param_count == 1:
                    result = filter_func(result)
                elif param_count == 2:
                    result = filter_func(result, *args)
                else:
                    result = filter_func(result, *args, **kwargs)
            except Exception as e:
                # 捕获异常，避免影响其他过滤器
                print(f"Error applying filter for event '{event_name}': {e}")
        
        return result
    
    def clear_filters(self, event_name: Optional[str] = None) -> None:
        """清除事件过滤器
        
        Args:
            event_name: 事件名称，如果为None则清除所有过滤器
        """
        with self._lock:
            if event_name is None:
                self._filters.clear()
            elif event_name in self._filters:
                del self._filters[event_name]
    
    def get_filters_count(self, event_name: str) -> int:
        """获取事件的过滤器数量
        
        Args:
            event_name: 事件名称
            
        Returns:
            int: 过滤器数量
        """
        with self._lock:
            if event_name not in self._filters:
                return 0
            return len(self._filters[event_name])
    
    def get_filtered_events(self) -> List[str]:
        """获取所有有过滤器的事件名称
        
        Returns:
            List[str]: 事件名称列表
        """
        with self._lock:
            return list(self._filters.keys())


class EventDebouncer:
    """事件防抖器，用于限制事件的触发频率"""
    
    def __init__(self, event_bus: EventBus, delay: float = 0.3):
        """初始化事件防抖器
        
        Args:
            event_bus: 事件总线实例
            delay: 防抖延迟时间（秒）
        """
        self._event_bus = event_bus
        self._delay = delay
        self._timers: Dict[str, threading.Timer] = {}
        self._pending_events: Dict[str, Tuple[List[Any], Dict[str, Any]]] = {}
        self._lock = threading.RLock()
    
    def debounce(self, event_name: str, *args, **kwargs) -> None:
        """防抖处理事件
        
        Args:
            event_name: 事件名称
            *args: 传递给事件的位置参数
            **kwargs: 传递给事件的关键字参数
        """
        with self._lock:
            # 存储待处理的事件参数
            self._pending_events[event_name] = (args, kwargs)
            
            # 取消之前的定时器
            if event_name in self._timers:
                self._timers[event_name].cancel()
                del self._timers[event_name]
            
            # 创建新的定时器
            timer = threading.Timer(self._delay, self._emit_debounced_event, args=[event_name])
            self._timers[event_name] = timer
            timer.daemon = True
            timer.start()
    
    def _emit_debounced_event(self, event_name: str) -> None:
        """发射防抖后的事件
        
        Args:
            event_name: 事件名称
        """
        with self._lock:
            # 检查是否有待处理的事件
            if event_name not in self._pending_events:
                return
            
            # 获取事件参数
            args, kwargs = self._pending_events[event_name]
            
            # 从待处理列表中移除
            del self._pending_events[event_name]
            
            # 如果有对应的定时器，也移除
            if event_name in self._timers:
                del self._timers[event_name]
        
        # 发射事件
        self._event_bus.publish(event_name, *args, **kwargs)
    
    def flush(self, event_name: Optional[str] = None) -> None:
        """立即发射所有待处理的事件
        
        Args:
            event_name: 事件名称，如果为None则发射所有待处理的事件
        """
        with self._lock:
            if event_name is None:
                # 发射所有待处理的事件
                event_names = list(self._pending_events.keys())
                for name in event_names:
                    self._emit_debounced_event(name)
            elif event_name in self._pending_events:
                # 发射特定事件
                self._emit_debounced_event(event_name)
    
    def cancel(self, event_name: Optional[str] = None) -> None:
        """取消待处理的事件
        
        Args:
            event_name: 事件名称，如果为None则取消所有待处理的事件
        """
        with self._lock:
            if event_name is None:
                # 取消所有待处理的事件
                for name in list(self._timers.keys()):
                    self._timers[name].cancel()
                    del self._timers[name]
                self._pending_events.clear()
            elif event_name in self._timers:
                # 取消特定事件
                self._timers[event_name].cancel()
                del self._timers[event_name]
                if event_name in self._pending_events:
                    del self._pending_events[event_name]
    
    def get_pending_count(self) -> int:
        """获取待处理的事件数量
        
        Returns:
            int: 待处理的事件数量
        """
        with self._lock:
            return len(self._pending_events)
    
    def set_delay(self, delay: float) -> None:
        """设置防抖延迟时间
        
        Args:
            delay: 防抖延迟时间（秒）
        """
        if delay >= 0:
            self._delay = delay
    
    def get_delay(self) -> float:
        """获取防抖延迟时间
        
        Returns:
            float: 防抖延迟时间（秒）
        """
        return self._delay


class EventThrottler:
    """事件节流器，用于限制事件的触发频率"""
    
    def __init__(self, event_bus: EventBus, interval: float = 0.3):
        """初始化事件节流器
        
        Args:
            event_bus: 事件总线实例
            interval: 节流间隔时间（秒）
        """
        self._event_bus = event_bus
        self._interval = interval
        self._last_emit_times: Dict[str, float] = {}
        self._pending_events: Dict[str, Tuple[List[Any], Dict[str, Any]]] = {}
        self._lock = threading.RLock()
        self._is_processing = False
    
    def throttle(self, event_name: str, *args, **kwargs) -> bool:
        """节流处理事件
        
        Args:
            event_name: 事件名称
            *args: 传递给事件的位置参数
            **kwargs: 传递给事件的关键字参数
            
        Returns:
            bool: 是否立即发射了事件
        """
        import time
        
        with self._lock:
            current_time = time.time()
            
            # 检查是否可以立即发射事件
            last_time = self._last_emit_times.get(event_name, 0)
            if current_time - last_time >= self._interval:
                # 立即发射事件
                self._last_emit_times[event_name] = current_time
                self._event_bus.publish(event_name, *args, **kwargs)
                
                # 如果有等待中的事件，清除它
                if event_name in self._pending_events:
                    del self._pending_events[event_name]
                
                return True
            else:
                # 存储最新的事件参数
                self._pending_events[event_name] = (args, kwargs)
                
                # 如果没有正在处理的定时器，启动一个
                if not self._is_processing:
                    self._is_processing = True
                    timer = threading.Timer(
                        self._interval - (current_time - last_time),
                        self._process_pending_events
                    )
                    timer.daemon = True
                    timer.start()
                
                return False
    
    def _process_pending_events(self) -> None:
        """处理所有待处理的事件"""
        import time
        
        # 获取待处理的事件
        pending_events = {}
        with self._lock:
            pending_events = self._pending_events.copy()
            self._pending_events.clear()
            self._is_processing = False
        
        # 发射所有待处理的事件
        current_time = time.time()
        for event_name, (args, kwargs) in pending_events.items():
            with self._lock:
                self._last_emit_times[event_name] = current_time
            self._event_bus.publish(event_name, *args, **kwargs)
    
    def flush(self, event_name: Optional[str] = None) -> None:
        """立即发射所有待处理的事件
        
        Args:
            event_name: 事件名称，如果为None则发射所有待处理的事件
        """
        import time
        
        with self._lock:
            current_time = time.time()
            
            if event_name is None:
                # 发射所有待处理的事件
                for name, (args, kwargs) in self._pending_events.items():
                    self._last_emit_times[name] = current_time
                    self._event_bus.publish(name, *args, **kwargs)
                self._pending_events.clear()
            elif event_name in self._pending_events:
                # 发射特定事件
                args, kwargs = self._pending_events[event_name]
                self._last_emit_times[event_name] = current_time
                self._event_bus.publish(event_name, *args, **kwargs)
                del self._pending_events[event_name]
            
            # 如果有正在处理的定时器，不需要取消，因为处理函数会检查待处理事件列表
    
    def cancel(self, event_name: Optional[str] = None) -> None:
        """取消待处理的事件
        
        Args:
            event_name: 事件名称，如果为None则取消所有待处理的事件
        """
        with self._lock:
            if event_name is None:
                self._pending_events.clear()
            elif event_name in self._pending_events:
                del self._pending_events[event_name]
    
    def get_pending_count(self) -> int:
        """获取待处理的事件数量
        
        Returns:
            int: 待处理的事件数量
        """
        with self._lock:
            return len(self._pending_events)
    
    def set_interval(self, interval: float) -> None:
        """设置节流间隔时间
        
        Args:
            interval: 节流间隔时间（秒）
        """
        if interval >= 0:
            self._interval = interval
    
    def get_interval(self) -> float:
        """获取节流间隔时间
        
        Returns:
            float: 节流间隔时间（秒）
        """
        return self._interval


# 创建全局事件总线实例
global_event_bus = EventBus()


# 导出常用函数
def subscribe(event_name: str, callback: Callable) -> bool:
    """订阅全局事件
    
    Args:
        event_name: 事件名称
        callback: 回调函数
        
    Returns:
        bool: 是否订阅成功
    """
    return global_event_bus.subscribe(event_name, callback)

def unsubscribe(event_name: str, callback: Callable) -> bool:
    """取消订阅全局事件
    
    Args:
        event_name: 事件名称
        callback: 回调函数
        
    Returns:
        bool: 是否取消订阅成功
    """
    return global_event_bus.unsubscribe(event_name, callback)

def unsubscribe_all(callback: Callable) -> int:
    """取消回调函数订阅的所有全局事件
    
    Args:
        callback: 回调函数
        
    Returns:
        int: 取消订阅的事件数量
    """
    return global_event_bus.unsubscribe_all(callback)

def publish(event_name: str, *args, **kwargs) -> int:
    """发布全局事件
    
    Args:
        event_name: 事件名称
        *args: 传递给回调函数的位置参数
        **kwargs: 传递给回调函数的关键字参数
        
    Returns:
        int: 成功调用的回调函数数量
    """
    return global_event_bus.publish(event_name, *args, **kwargs)

def clear_events(event_name: Optional[str] = None) -> None:
    """清除全局事件订阅
    
    Args:
        event_name: 事件名称，如果为None则清除所有事件
    """
    global_event_bus.clear(event_name)

def enable_events() -> None:
    """启用全局事件总线"""
    global_event_bus.enable()

def disable_events() -> None:
    """禁用全局事件总线"""
    global_event_bus.disable()

def get_event_names() -> List[str]:
    """获取所有注册的全局事件名称
    
    Returns:
        List[str]: 事件名称列表
    """
    return global_event_bus.get_event_names()


# 定义一些常用的事件名称
class EventNames:
    """常用事件名称常量"""
    # 应用程序事件
    APP_STARTED = "app_started"
    APP_CLOSING = "app_closing"
    APP_CLOSED = "app_closed"
    APP_CONFIG_CHANGED = "app_config_changed"
    
    # 文件事件
    FILE_OPENED = "file_opened"
    FILE_SAVED = "file_saved"
    FILE_CREATED = "file_created"
    FILE_DELETED = "file_deleted"
    FILE_RENAMED = "file_renamed"
    FILE_CONTENT_CHANGED = "file_content_changed"
    
    # 项目事件
    PROJECT_OPENED = "project_opened"
    PROJECT_CLOSED = "project_closed"
    PROJECT_SAVED = "project_saved"
    PROJECT_CREATED = "project_created"
    PROJECT_CONFIG_CHANGED = "project_config_changed"
    
    # 编辑器事件
    EDITOR_OPENED = "editor_opened"
    EDITOR_CLOSED = "editor_closed"
    EDITOR_ACTIVATED = "editor_activated"
    EDITOR_TEXT_CHANGED = "editor_text_changed"
    EDITOR_SELECTION_CHANGED = "editor_selection_changed"
    EDITOR_CURSOR_MOVED = "editor_cursor_moved"
    EDITOR_FOCUS_GAINED = "editor_focus_gained"
    EDITOR_FOCUS_LOST = "editor_focus_lost"
    
    # 设计器事件
    DESIGNER_OPENED = "designer_opened"
    DESIGNER_CLOSED = "designer_closed"
    DESIGNER_COMPONENT_ADDED = "designer_component_added"
    DESIGNER_COMPONENT_REMOVED = "designer_component_removed"
    DESIGNER_COMPONENT_MOVED = "designer_component_moved"
    DESIGNER_COMPONENT_RESIZED = "designer_component_resized"
    DESIGNER_COMPONENT_SELECTED = "designer_component_selected"
    DESIGNER_PROPERTY_CHANGED = "designer_property_changed"
    
    # 用户界面事件
    UI_THEME_CHANGED = "ui_theme_changed"
    UI_FONT_CHANGED = "ui_font_changed"
    UI_LAYOUT_CHANGED = "ui_layout_changed"
    
    # 资源事件
    RESOURCE_ADDED = "resource_added"
    RESOURCE_REMOVED = "resource_removed"
    RESOURCE_UPDATED = "resource_updated"
    
    # 构建和运行事件
    BUILD_STARTED = "build_started"
    BUILD_COMPLETED = "build_completed"
    BUILD_FAILED = "build_failed"
    RUN_STARTED = "run_started"
    RUN_COMPLETED = "run_completed"
    RUN_FAILED = "run_failed"
    
    # 调试事件
    DEBUG_STARTED = "debug_started"
    DEBUG_STOPPED = "debug_stopped"
    DEBUG_BREAKPOINT_SET = "debug_breakpoint_set"
    DEBUG_BREAKPOINT_REMOVED = "debug_breakpoint_removed"
    DEBUG_PAUSED = "debug_paused"
    DEBUG_RESUMED = "debug_resumed"
    
    # 搜索事件
    SEARCH_STARTED = "search_started"
    SEARCH_COMPLETED = "search_completed"
    SEARCH_RESULT_FOUND = "search_result_found"
    
    # 通知事件
    NOTIFICATION_INFO = "notification_info"
    NOTIFICATION_WARNING = "notification_warning"
    NOTIFICATION_ERROR = "notification_error"
    NOTIFICATION_SUCCESS = "notification_success"